package com.zhangjg.database;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;


public class IdTableGenerator{
	
	public static Log log = LogFactory.getLog(IdTableGenerator.class);
	public static String KEYGEN_TABLE_NAME = "PUB_KEYGEN";
	
	public static int ALLOC_RANGE = 10;
	
	Map<String, IdHolder> holderMap = new java.util.concurrent.ConcurrentHashMap<String, IdHolder>();
	
	public long generate(String tableName) {
		IdHolder holder = holderMap.get(tableName);
		if (holder == null) {
			holder = new IdHolder();
			holderMap.put(tableName, holder);
		}
		synchronized (holder) {
			if (holder.needAlloc()) {
				long lastUsedId = alloc(tableName);
				holder.currentId = lastUsedId;
				holder.limit = lastUsedId + ALLOC_RANGE - 1;
			} else {
				holder.currentId ++;
			}
		}
		
		return holder.currentId;
	}
	
	static class IdHolder {
		long currentId;
		long limit;
		boolean needAlloc() {return currentId >= limit; }
	}
	
	
	public long alloc(String tableName) {
		long result = getLastUsedId(tableName);
		if(result == 0){
			deleteIdTable(tableName);
			initIdTable(tableName);
			//初始化完重新拿一次
			result = getLastUsedId(tableName);
		}
		updateLastUsedId(tableName,ALLOC_RANGE);
		return result;
	}
	
	

    public long getLastUsedId(String tableName){
		long maxId = 0;
		TableDao<Object> base = new TableDao<Object>();
		String sql = "select LAST_ID from "+KEYGEN_TABLE_NAME+" where TABLE_NAME = ?";
		List<Object> params = new ArrayList<Object>();
		params.add(tableName);
		List<Object>  list = base.select(sql,params);
		if(list!=null&&list.size()>0)
		    maxId = Long.parseLong(list.get(0).toString());
		return maxId;
	}
	
	public void updateLastUsedId(String tableName,int step) {
		String sql = "update "+KEYGEN_TABLE_NAME+" set LAST_ID = LAST_ID + ? where TABLE_NAME = ?";
		TableDao<Object> base = new TableDao<Object>();
		List<Object> params = new ArrayList<Object>();
		params.add(step);
		params.add(tableName);
		base.excute(sql, params);
	}
	
	public void initIdTable(String tableName){
	    TableDao<Object> base = new TableDao<Object>();
        base.setConnection(DBManager.getConnection());
        long maxId = 0;
        String sql = "select max(UUID) from " + tableName;
        List<Object> list = base.select(sql, null);
        if (list != null && list.size() > 0)
            maxId = Long.parseLong(list.get(0).toString());
        // 更新
        sql = "insert into " + KEYGEN_TABLE_NAME + " (TABLE_NAME, LAST_ID) values (?, ?)";
        List<Object> params = new ArrayList<Object>();
        params.add(tableName);
        params.add(maxId);
        base.excute(sql, params);
        base.close();
	}
	
	public void deleteIdTable(String tableName){
		String sql = "delete from "+KEYGEN_TABLE_NAME+" where TABLE_NAME = ?";
		SuperDao<Object> base = new SuperDao<Object>();
		List<Object> params = new ArrayList<Object>();
		params.add(tableName);
		base.excute(sql, params);
	}
	
	public static void main(String[] args) {
	    System.out.println(new IdTableGenerator().getLastUsedId("SA"));
    }
	
}
